package org.example.myleet.p1600;

import org.example.myleet.Utils.Assert;
import org.example.myleet.Utils.JsonUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        List<String> inputs = JsonUtils.parse("[\"org.example.myleet.p1600.ThroneInheritance\", \"birth\", \"birth\", \"birth\", \"birth\", \"birth\", \"birth\", \"getInheritanceOrder\", \"death\", \"getInheritanceOrder\"]", List.class);
        List<List<String>> inputParams = JsonUtils.parse("[[\"king\"], [\"king\", \"andy\"], [\"king\", \"bob\"], [\"king\", \"catherine\"], [\"andy\", \"matthew\"], [\"bob\", \"alex\"], [\"bob\", \"asha\"], [null], [\"bob\"], [null]]\n", List.class);
        List<List<String>> correctAnswers = JsonUtils.parse("[null, null, null, null, null, null, null, [\"king\", \"andy\", \"matthew\", \"bob\", \"alex\", \"asha\", \"catherine\"], null, [\"king\", \"andy\", \"matthew\", \"alex\", \"asha\", \"catherine\"]]\n", List.class);
        Class<ThroneInheritance> inheritanceClass = (Class<ThroneInheritance>) Class.forName(inputs.get(0));
        Constructor<ThroneInheritance> constructor = inheritanceClass.getConstructor(String.class);
        ThroneInheritance instance = constructor.newInstance(inputParams.get(0).get(0));
        Method[] methods = instance.getClass().getDeclaredMethods();
        Map<String, Method> methodMap = Arrays.stream(methods).collect(Collectors.toMap(Method::getName, Function.identity()));
        for (int i = 1; i < inputs.size(); ++i) {
            Method m = methodMap.get(inputs.get(i));
            String[] param = inputParams.get(i).get(0) == null ? null : inputParams.get(i).toArray(new String[0]);
            Object result;
            if (param == null) {
                result = m.invoke(instance);
            } else {
                result = m.invoke(instance, param);
            }
            Assert.isTrue(Assert.isObjectPass(correctAnswers.get(i), result));
        }
    }
}
